package geneontofx.go;

import java.util.ArrayList;
import java.util.Objects;


public class OntologyTerm {
    private String id;
    private String name;
    private String namespace;
    private String definition;
    //Initial relations:
    private ArrayList<OntologyTerm> isA;
    private ArrayList<OntologyTerm> partOf;
    private ArrayList<OntologyTerm> regulates;
    private ArrayList<OntologyTerm> hasPart;
    private ArrayList<OntologyTerm> occursIn;
    //-- end of relations
    private boolean obsolete;
    private boolean basic;
    private boolean complete;
    private boolean hasParents;
    private boolean hasChildren;
    
    //Processed relations:
    private ArrayList<ArrayList> parents;
    private ArrayList<ArrayList> children;
    
    public enum Relations {
        ISA, PARTOF, HASPART, REGULATES, OCCURSIN;
    }

    public OntologyTerm() {
        this.obsolete = false;
    }

    public OntologyTerm(String id) {
        this.id = id;
        this.basic = true;
    }
    
    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public void setDefinition(String definition) {
        this.definition = definition;
    }
    
    public void addRelation(String id, Relations rel) {
        ArrayList<OntologyTerm> targetList = null;
        switch(rel) {
            case ISA:
                targetList = isA;
                break;
            case PARTOF:
                targetList = partOf;
                break;
            case HASPART:
                targetList = hasPart;
                break;
            case REGULATES:
                targetList = regulates;
                break;
            case OCCURSIN:
                targetList = occursIn;
                break;
        }        
        OntologyTerm newTerm = new OntologyTerm(id);
        if(targetList == null) {
            targetList = new ArrayList<>();
        }
        if(rel == Relations.HASPART) newTerm.setHasChildren(true);
        else newTerm.setHasParents(true);
        targetList.add(newTerm);
    }
    
    public String getId() {
        return id;
    }
    
    public ArrayList<ArrayList> getParents() {
        if(parents  == null) {
            parents = new ArrayList<>();
            parents.add(isA);
            parents.add(partOf);
            parents.add(regulates);
            parents.add(occursIn);
        }
        return parents;
    }

    public ArrayList<ArrayList> getChildren() {
        if(children == null) {
            children = new ArrayList<>();
            children.add(hasPart);
        }
        return children;
    }

    public boolean isObsolete() {
        return obsolete;
    }
    
    public void setObsolete(boolean obsolete) {
        this.obsolete = obsolete;
    }

    public boolean isBasic() {
        return basic;
    }

    public void setBasic(boolean basic) {
        this.basic = basic;
    }

    public boolean isComplete() {
        return complete;
    }

    public void setComplete(boolean complete) {
        this.complete = complete;
    }
    
    public void verifyComplete() {
        if(!basic && !hasParents && !hasChildren && !obsolete) {
            this.complete = true;
        }
        else this.complete = false;
    }

    public boolean hasParents() {
        return hasParents;
    }

    public void setHasParents(boolean hasParents) {
        this.hasParents = hasParents;
    }

    public boolean hasChildren() {
        return hasChildren;
    }

    public void setHasChildren(boolean hasChildren) {
        this.hasChildren = hasChildren;
    }
    
    

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 71 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final OntologyTerm other = (OntologyTerm) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "OntologyTerm{" + "id= " + id + '}';
    }
    
    
}
